home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / V2 / DJLSR200.ZIP / src / libc / crt0 / crt1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-24  |  3.6 KB  |  147 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <libc/stubs.h>
  4. #include <crt0.h>
  5. #include <string.h>
  6. #include <libc/internal.h>
  7. #include <stdlib.h>
  8. #include <go32.h>
  9. #include <stubinfo.h>
  10. #include <dpmi.h>
  11. #include <libc/farptrgs.h>
  12. #include <pc.h>
  13. #include <libc/bss.h>
  14.  
  15. /* Global variables */
  16.  
  17. #define ds _my_ds()
  18.  
  19. int __bss_count = 1;
  20.  
  21. char **environ;
  22. int _crt0_startup_flags;    /* default to zero unless app overrides them */
  23.  
  24. int __crt0_argc;
  25. char **__crt0_argv;
  26.  
  27. /* Local variables */
  28.  
  29. static void
  30. setup_core_selector(void)
  31. {
  32.   int c = __dpmi_allocate_ldt_descriptors(1);
  33.   if (c == -1)
  34.   {
  35.     _dos_ds = 0;
  36.     return;
  37.   }
  38.   _dos_ds = c;
  39.  
  40.   __dpmi_set_segment_limit(_dos_ds, 16 * 1024 * 1024 - 1);
  41. }
  42.  
  43. static void
  44. setup_screens(void)
  45. {
  46.   if(_farpeekw(_dos_ds, 0xffff3) == 0xfd80)    /* NEC PC98 ? */
  47.   {
  48.     ScreenPrimary = ScreenSecondary = 0xa0000;
  49.   }
  50.   else if (_farpeekb(_dos_ds, 0x449) == 7)
  51.   {
  52.     ScreenPrimary = 0xb0000;
  53.     ScreenSecondary = 0xb8000;
  54.   }
  55.   else
  56.   {
  57.     ScreenPrimary = 0xb8000;
  58.     ScreenSecondary = 0xb0000;
  59.   }
  60. }
  61.  
  62. static void
  63. setup_go32_info_block(void)
  64. {
  65.   __dpmi_version_ret ver;
  66.   __dpmi_regs r;
  67.  
  68.   r.x.ax = 0x1687;
  69.   __dpmi_int(0x2f, &r);
  70.  
  71.   __dpmi_get_version(&ver);
  72.  
  73.   _go32_info_block.size_of_this_structure_in_bytes = sizeof(_go32_info_block);
  74.   __tb = _stubinfo->ds_segment * 16;
  75.   _go32_info_block.size_of_transfer_buffer = _stubinfo->minkeep;
  76.   _go32_info_block.pid = _stubinfo->psp_selector;
  77.   _go32_info_block.master_interrupt_controller_base = ver.master_pic;
  78.   _go32_info_block.slave_interrupt_controller_base = ver.slave_pic;
  79.   _go32_info_block.linear_address_of_stub_info_structure = 0xffffffffU; /* force error */
  80.   _go32_info_block.linear_address_of_original_psp = _stubinfo->ds_segment * 16 - 256;
  81.   _go32_info_block.run_mode = _GO32_RUN_MODE_DPMI;
  82.   _go32_info_block.run_mode_info = r.x.dx;
  83. }
  84.  
  85. char *__dos_argv0;
  86.  
  87. static void
  88. setup_environment(void)
  89. {
  90.   char *dos_environ = alloca(_stubinfo->env_size), *cp;
  91.   short env_selector;
  92.   int env_count=0;
  93.   movedata(_stubinfo->psp_selector, 0x2c, ds, (int)&env_selector, 2);
  94.   movedata(env_selector, 0, ds, (int)dos_environ, _stubinfo->env_size);
  95.   cp = dos_environ;
  96.   do {
  97.     env_count++;
  98.     while (*cp) cp++; /* skip to NUL */
  99.     cp++; /* skip to next character */
  100.   } while (*cp); /* repeat until two NULs */
  101.   environ = (char **)malloc((env_count+1) * sizeof(char *));
  102.   if (environ == 0)
  103.     return;
  104.  
  105.   cp = dos_environ;
  106.   env_count = 0;
  107.   do {
  108.     /* putenv assumes each string is malloc'd */
  109.     environ[env_count] = (char *)malloc(strlen(cp)+1);
  110.     strcpy(environ[env_count], cp);
  111.     env_count++;
  112.     while (*cp) cp++; /* skip to NUL */
  113.     cp++; /* skip to next character */
  114.   } while (*cp); /* repeat until two NULs */
  115.   environ[env_count] = 0;
  116.   
  117.   __dos_argv0 = (char *)malloc(strlen(cp + 3)+1);
  118.   if (__dos_argv0 == 0)
  119.     abort();
  120.   strcpy(__dos_argv0, cp+3);
  121. }
  122.  
  123. extern void __main(void);
  124. extern int  main(int, char **, char **);
  125. extern void _crt0_init_mcount(void);    /* For profiling */
  126.  
  127. void
  128. __crt1_startup(void)
  129. {
  130.   char *pn;
  131.   __bss_count ++;
  132.   __crt0_argv = 0;
  133.   setup_core_selector();
  134.   setup_screens();
  135.   setup_go32_info_block();
  136.   __djgpp_exception_setup();
  137.   setup_environment();
  138.   __crt0_setup_arguments();
  139.   pn = __crt0_argv ? __crt0_argv[0] : __dos_argv0;
  140.   __crt0_load_environment_file(pn);
  141.   _npxsetup(pn);
  142.   _crt0_init_mcount();
  143.   __main();
  144.   exit(main(__crt0_argc, __crt0_argv, environ));
  145. }
  146.  
  147.